package nayasis.common.db.sql;

import java.util.List;
import java.util.Map;

import nayasis.common.exception.unchecked.DatabaseException;
import nayasis.common.model.NData;
import nayasis.common.model.NMultiData;
import nayasis.common.model.NVo;

/**
 * Statement
 *
 * <pre>
 * 이를 통해 DB에 접근하여 데이터를 조회하거나 조작한다.
 *
 * Statement stmt = DatabaseManager.getStatement( "DELETE FROM TABLE WHERE id = :id" );
 * stmt.setString( "id", "merong" );
 *
 * stmt.executeUpdate();
 * </pre>
 *
 * @author nayasis
 */
public interface Statement {

	/**
	 * SQL 문장을 세팅한다.
	 *
	 * @param sql SQL 문장
	 * @return Statement
	 */
	public Statement setSql( String sql );

	/**
	 * SQL 문장을 세팅한다.
	 *
	 * @param sql SQL 문장
	 * @param dbSpec dbSpec
	 * @return Statement
	 */
	public Statement setSql( String sql, String dbSpec );

	/**
	 * SELECT SQL 문장을 실행하여 단건 데이터를 조회한다.
	 *
	 * @throws DatabaseException DB 처리 오류시
	 */
	public NData executeQueryAsSingle() throws DatabaseException;

	/**
	 * SELECT SQL 문장을 실행하여 다건 데이터를 조회한다.
	 *
	 * @throws DatabaseException DB 처리 오류시
	 */
	public NMultiData executeQuery() throws DatabaseException;

	/**
	 * INSERT, UPDATE, DELETE (DML 구문) SQL 문장을 실행한다.
	 *
	 * @return 영향을 받은 DB 테이블 row 건수
	 * @throws DatabaseException DB 처리 오류시
	 */
	public int executeUpdate() throws DatabaseException;

	/**
     * SQL 문장의 '<font color='red'>:*</font>' 형식의 문자에 할당할 값을 세팅한다.
     *
     * <pre>
     * Statement stmt = DatabaseManager.getStatement(
     *    <font color='blue'>"DELETE FROM TABLE WHERE birth_year = <font color=red>:memberYear</font> AND age = <font color=red>:memberAge</font>"</font>
     * );
     *
     * stmt.setInt( <font color=red>"memberYear"</font>, 1990 );
     * stmt.setInt( <font color=red>"memberAge"</font>,  25   );
     *
     * -->
     * <font color='blue'>"DELETE FROM TABLE WHERE birth_year = <font color=red>1990</font> AND age = <font color=red>25</font>"</font>
     *
     * </pre>
     *
     * @param paramName ':*' 형식의 바인딩 파라미터 명
     * @param value 할당할 값
     */
	public Statement setInt( String paramName, int value );

    /**
     * SQL 문장의 '<font color='red'>:*</font>' 형식의 문자에 할당할 값을 세팅한다.
     *
     * <pre>
     * Statement stmt = DatabaseManager.getStatement(
     *    <font color='blue'>"DELETE FROM TABLE WHERE birth_year = <font color=red>:memberYear</font> AND age = <font color=red>:memberAge</font>"</font>
     * );
     *
     * stmt.setLong( <font color=red>"memberYear"</font>, 1990 );
     * stmt.setLong( <font color=red>"memberAge"</font>,  25   );
     *
     * -->
     * <font color='blue'>"DELETE FROM TABLE WHERE birth_year = <font color=red>1990</font> AND age = <font color=red>25</font>"</font>
     *
     * </pre>
     *
     * @param paramName ':*' 형식의 바인딩 파라미터 명
     * @param value 할당할 값
     */
	public Statement setLong( String paramName, long value );

    /**
     * SQL 문장의 '<font color='red'>:*</font>' 형식의 문자에 할당할 값을 세팅한다.
     *
     * <pre>
     * Statement stmt = DatabaseManager.getStatement(
     *    <font color='blue'>"DELETE FROM TABLE WHERE birth_year = <font color=red>:memberYear</font> AND age = <font color=red>:memberAge</font>"</font>
     * );
     *
     * stmt.setFloat( <font color=red>"memberYear"</font>, 1990.5 );
     * stmt.setFloat( <font color=red>"memberAge"</font>,  25.7   );
     *
     * -->
     * <font color='blue'>"DELETE FROM TABLE WHERE birth_year = <font color=red>1990.5</font> AND age = <font color=red>25.7</font>"</font>
     *
     * </pre>
     *
     * @param paramName ':*' 형식의 바인딩 파라미터 명
     * @param value 할당할 값
     */
	public Statement setFloat( String paramName, float value );

    /**
     * SQL 문장의 '<font color='red'>:*</font>' 형식의 문자에 할당할 값을 세팅한다.
     *
     * <pre>
     * Statement stmt = DatabaseManager.getStatement(
     *    <font color='blue'>"DELETE FROM TABLE WHERE birth_year = <font color=red>:memberYear</font> AND age = <font color=red>:memberAge</font>"</font>
     * );
     *
     * stmt.setDouble( <font color=red>"memberYear"</font>, 1990.5 );
     * stmt.setDouble( <font color=red>"memberAge"</font>,  25.7   );
     *
     * -->
     * <font color='blue'>"DELETE FROM TABLE WHERE birth_year = <font color=red>1990.5</font> AND age = <font color=red>25.7</font>"</font>
     *
     * </pre>
     *
     * @param paramName ':*' 형식의 바인딩 파라미터 명
     * @param value 할당할 값
     */
	public Statement setDouble( String paramName, double value );

	/**
     * SQL 문장의 '<font color='red'>:*</font>' 형식의 문자에 할당할 값을 세팅한다.
     *
     * <pre>
     * Statement stmt = DatabaseManager.getStatement(
     *    <font color='blue'>"DELETE FROM TABLE WHERE id = <font color=red>:memberId</font> AND name = <font color=red>:memberName</font>"</font>
     * );
     *
     * stmt.setString( <font color=red>"memberId"</font>,   "nayasis" );
     * stmt.setString( <font color=red>"memnerName"</font>, "teacher" );
     *
     * -->
     * <font color='blue'>"DELETE FROM TABLE WHERE id = <font color=red>'nayasis'</font> AND name = <font color=red>'teacher'</font>"</font>
     *
     * </pre>
     *
     * @param paramName ':*' 형식의 바인딩 파라미터 명
     * @param value 할당할 값
     */
	public Statement setString( String paramName, String value );

	/**
     * SQL 문장의 '<font color='red'>:*</font>' 형식의 문자에 할당할 배열값을 세팅한다. (IN절 세팅에 주로 사용됨)
     *
     * <pre>
     * Statement stmt = DatabaseManager.getStatement(
     *    <font color='blue'>"DELETE FROM TABLE WHERE name = <font color=red>:name</font> AND id IN ( <font color=red>:ids</font> )"</font>
     * );
     *
     * List&lt;String&gt; idList = new ArrayList&lt;String&gt; ();
     *
     * idList.add( "merong" );
     * idList.add( "simjin" );
     *
     * stmt.setArray( <font color=red>"ids"</font>, idList );
     *
     * -->
     * <font color='blue'>DELETE FROM TABLE WHERE name = <font color=red>?</font> AND id IN ( <font color=red>'merong', 'simjin'</font> )</font>
     *
     * </pre>
     *
     * @param paramName ':*' 형식의 바인딩 파라미터 명
     * @param value 할당할 값
     */
	public Statement setArray( String paramName, List<?> value );

    /**
     * SQL 문장의 '<font color='red'>:*</font>' 형식의 문자에 할당할 배열값을 세팅한다. (IN절 세팅에 주로 사용됨)
     *
     * <pre>
     * Statement stmt = DatabaseManager.getStatement(
     *    <font color='blue'>"DELETE FROM TABLE WHERE name = <font color=red>:name</font> AND id IN ( <font color=red>:ids</font> )"</font>
     * );
     *
     * String[] idList = new String[] { "merong", "simjin" };
     *
     * stmt.setArray( <font color=red>2</font>, idList );
     *
     * -->
     * <font color='blue'>DELETE FROM TABLE WHERE name = <font color=red>?</font> AND id IN ( <font color=red>'merong', 'simjin'</font> )</font>
     *
     * </pre>
     *
     * @param paramName ':*' 형식의 바인딩 파라미터 명
     * @param value 할당할 값
     */
	public Statement setArray( String paramName, Object[] value );

    /**
     * SQL 문장의 '<font color='red'>:*</font>' 형식의 바인딩 문자에<br/>
     * Entity 필드명과 일치하는 값을 자동으로 할당한다.
     *
     * <pre>
     * Statement stmt = DatabaseManager.getStatement(
     *    <font color='blue'>"DELETE FROM TABLE WHERE name=<font color=red>:memberName</font> AND id=<font color=red>:memberId</font>"</font>
     * );
     *
     * MemberEntity에 memberId라는 이름의 필드와 memberName이라는 이름의 필드가 존재한다고 가정하면,
     *
     * MemberEntity <font color=green>param</font> = new MemberEntity();
     * param.setMemberId( "merong" );
     * param.setMemberName( "정화수" );
     *
     * stmt.setEntity( <font color=green>param</font> );
     *
     * -->
     * <font color='blue'>DELETE FROM TABLE WHERE name=<font color=red>'정화수'</font> AND id=<font color=red>'merong'</font> </font>
     *
     * </pre>
     *
     * @param entity 바인딩할 파라미터 ( 필드명은 파라미터명으로, 필드값은 파라미터 값으로 사용됨)
     */
	public Statement setEntity( NVo entity );

    /**
     * SQL 문장의 '<font color='red'>:*</font>' 형식의 바인딩 문자에<br/>
     * Map의 key값에 일치하는 value를 자동으로 할당한다.
     *
     * <pre>
     * Statement stmt = DatabaseManager.getStatement(
     *    <font color='blue'>"DELETE FROM TABLE WHERE name=<font color=red>:memberName</font> AND id=<font color=red>:memberId</font>"</font>
     * );
     *
     * Map&lt;String, String&rt; <font color=green>param</font> = new HashMap&lt;String, String&rt;();
     * param.put( <font color=red>"memberId"</font>,   "merong" );
     * param.put( <font color=red>"memberName</font>", "정화수" );
     *
     * stmt.setEntity( <font color=green>param</font> );
     *
     * -->
     * <font color='blue'>DELETE FROM TABLE WHERE name=<font color=red>'정화수'</font> AND id=<font color=red>'merong'</font> </font>
     *
     * </pre>
     *
     * @param entity 바인딩할 파라미터 ( 필드명은 파라미터명으로, 필드값은 파라미터 값으로 사용됨)
     */
	public Statement setEntity( Map<String, ?> entity );

}